#ifndef __LOGO_INTERPRET_H__
#define __LOGO_INTERPRET_H__

#include "logo_lib.h"
#include "logo_lib_p.h"
#include "token.h"
#include "parse.h"
#include "iexec.h"


typedef struct tag_variable_t {
   list_node_t node_head;
   value_t     value;
} variable_t;

typedef int (*predefined_routine_f) (value_t* paras, int para_numbers, value_t* result);

#define LOGO_STACK_DEPTH 1024

typedef struct tag_routine_t {
   list_node_t                node_head;
   predefined_routine_f       func; // if func != NULL, this is a predefined routine.
   tree_node_t*               tree; //if func == NULL, the routine is defined by tree.
} routine_t;

#define next_node node_head.next
#define node_id node_head.id_str

class stack_t 
{
public:
   stack_t ();
   virtual ~stack_t();

   int            top;                       // Top of the stack, initialize as -1.
   routine_t*     rtn[LOGO_STACK_DEPTH];     // Store the pointers to rtn, used for getting routine name.
                                             //  should not delete the pointers here. 
   variable_t*    var[LOGO_STACK_DEPTH];     // The variable list of each rtn call in stack. 
                                             //  should be freed from this sructure.
   unsigned int   lineno[LOGO_STACK_DEPTH];  // Current line nunmber.
};

class rte_t 
{
public:
   rte_t();
   virtual ~rte_t();

   stack_t        stack;
   ExecControl    control;
   routine_t*     rtn_lst;
   HANDLE         mutex;
   i_exec_t*      exec;
   int            break_continue_line_no;
};

#define cur_var_list(rte) (rte->stack.var[rte->stack.top])
#define cur_rtn(rte) (rte->stack.rtn[rte->stack.top])
#define cur_lineno(rte) (rte->stack.lineno[rte->stack.top])
#define rte_rtn(rte,nIdxStack) (rte->stack.rtn[nIdxStack])

list_node_t* find_in_list (list_node_t* list, const char* id_str);

void delete_variable (variable_t* v);
void delete_variable_list (variable_t* list);

routine_t* new_routine ();
void delete_routine (routine_t* r);
void delete_routine_list (routine_t* list);

int exec_routine (rte_t* rte, routine_t* rtn, value_t* paras, int para_numer, value_t* result);

#endif /* __LOGO_INTERPRET_H__*/
